home *** CD-ROM | disk | FTP | other *** search
/ Compendium Deluxe 2 / LSD and 17bit Compendium Deluxe - Volume II.iso / a / prog / asmsrc / thesource-7.lha / Source / Articles / Stereoscopic / SegaGlasses.lha / SegaGlasses / segavga.c < prev    next >
C/C++ Source or Header  |  1992-08-02  |  14KB  |  531 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include "segavga.h"
  4. #include "mode_x.h"
  5. #include "dgif.h"
  6.  
  7. #define OPTIONS "a:bc:d:gimp:qr:"
  8.  
  9. FILE *f;
  10. char prog_name[30];
  11. unsigned int page,
  12.              lines,
  13.              bad_code_count,
  14.              debug = 0,         /* debug = 0  -  No debug messages     */
  15.                                 /*       = 1  -  Image Desc one        */
  16.                                 /*       = 2  -  Image Desc two        */
  17.                                 /*       = 3  -  Screen Desc           */
  18.                                 /*       = 4  -  All three (use more!) */
  19.              y;
  20.  
  21.  
  22. void usage(void)
  23. {
  24.     printf("\nUsage: %s [options] filename.gif\n\n", prog_name);
  25.     printf("Options are:  -b    : Blank screen during decode\n");
  26.     printf("              -g    : Apply grey scale to map\n");
  27.     printf("              -i    : Ignore local color maps\n");
  28.     printf("              -m    : Use grey scale map\n");
  29.     printf("              -q    : Disable info at end\n");
  30.     printf("              -a x  : Port address in hex\n");
  31.     printf("              -c x  : Comm port [1..4]\n");
  32.     printf("              -d x  : Debug level [1..4]\n");
  33.     printf("              -p x  : External palette file\n\n");
  34.     printf("Where <x> is either a number or a filename.\n");
  35.     printf("Example: %s -i -d 3 -a 2f8\n", prog_name);
  36.     exit(-1);
  37. }
  38.  
  39.  
  40. void global_stats(GIFDesc *gd)
  41. {
  42.     unsigned char global_map, col_res, bpp;
  43.     unsigned int  colors;
  44.  
  45.     global_map = gd->ColInfo >> 7;
  46.     col_res = ((gd->ColInfo & 0x70) >> 4) + 1;
  47.     bpp = (gd->ColInfo & 0x07) + 1;
  48.     colors = 1 << bpp;
  49.  
  50.     printf("Screen width: %d\n", gd->Width);
  51.     printf("Screen height: %d\n", gd->Height);
  52.     printf("Screen color info: 0x%.2x\n", gd->ColInfo);
  53.     printf("Screen background: %d\n", gd->BackGround);
  54.     printf("Screen aspect ratio: %d\n", gd->PixelAspect);
  55.     printf("Color resolution: %d bits\n", col_res);
  56.     printf("Bits per pixel: %d\n", bpp);
  57.  
  58.     if (global_map)
  59.     {
  60.         printf("Global colormap present.\n");
  61.         printf("There are %d colors in the global color map.\n\n", colors);
  62.     }
  63.     else
  64.     {
  65.         printf("Global colormap absent.\n\n");
  66.         printf("Will use local color map, if found.\n\n");
  67.         printf("Press any key to continue.......");
  68.         while (!kbhit());
  69.         getch();
  70.     }
  71. }
  72.  
  73. void local_stats(ImageDesc *id, unsigned char sep)
  74. {
  75.     unsigned char local_map, interlaced, col_res, bpp;
  76.     unsigned int  colors;
  77.  
  78.     local_map = id->Info >> 7;
  79.     interlaced = (id->Info & 0x40) == 0x40;
  80.     bpp = (id->Info & 0x07) + 1;
  81.     colors = 1 << bpp;
  82.  
  83.     printf("Image separator is '%c'\n", sep);
  84.     printf("Image left: %d\n", id->Left);
  85.     printf("Image top: %d\n", id->Top);
  86.     printf("Image width: %d\n", id->Width);
  87.     printf("Image height: %d\n", id->Height);
  88.     printf("Image info: 0x%.2x\n", id->Info);
  89.     printf("Color resolution: %d bits\n", col_res);
  90.     printf("Bits per pixel: %d\n", bpp);
  91.  
  92.     if (interlaced)
  93.     {
  94.         if (!debug)
  95.             end320x400mode();
  96.         printf("Image is interlaced.\n");
  97.         printf("Cannot handle it!\n");
  98.         if (!debug)
  99.             exit(-1);
  100.     }
  101.     else
  102.         printf("Image is not interlaced.\n");
  103.  
  104.     if (local_map)
  105.     {
  106.         printf("Local colormap present.\n");
  107.         printf("There are %d colors in the local color map.\n\n", colors);
  108.     }
  109.     else
  110.         printf("Local colormap absent.\n\n");
  111. }
  112.  
  113.  
  114. void disable_greyscale(unsigned char c)
  115. {
  116.     union REGS regs;
  117.  
  118.     regs.h.ah = 0x12;
  119.     regs.h.al = c;
  120.     regs.h.bl = 0x33;
  121.  
  122.     int86(0x10, ®s, ®s);
  123. }
  124.  
  125. void blank_screen(unsigned char c)
  126. {
  127.     union REGS regs;
  128.  
  129.     regs.h.ah = 0x12;
  130.     regs.h.al = c;
  131.     regs.h.bl = 0x36;
  132.  
  133.     int86(0x10, ®s, ®s);
  134. }
  135.  
  136. int out_line(unsigned char pixels[], int linelen)
  137. {
  138.     register int x;
  139.  
  140.     if (!debug)
  141.     {
  142.         setactpage(page);               /* Select page to write pixels into */
  143.  
  144.         for(x = 0; x < linelen; x++)
  145.             writepixel(x, y, pixels[x]);
  146.         y++;
  147.  
  148.         if (lines <= 200)
  149.         {
  150.             for(x = 0; x < linelen; x++)
  151.                 writepixel(x, y, pixels[x]);
  152.             y++;
  153.         }
  154.     }
  155.  
  156.     return 0;
  157. }
  158.  
  159.  
  160. int get_byte(void)
  161. {
  162.     return (int) fgetc(f);
  163. }
  164.  
  165.  
  166. void main(int argc, char *argv[])
  167. {
  168.     Palette pal, local_pal;
  169.     GIFDesc gd;
  170.     ImageDesc id;
  171.     char *Sig[6], *GIFSig = "GIF89a", separator, *gif_file, map_file[30];
  172.     unsigned char local_map, bpp, global_map, blank,
  173.                   ignore_local_maps, external_map, grey, greymap, quiet;
  174.     unsigned int base, loop, colors, error_count1, error_count2;
  175.     int          success1, success2, c;
  176.  
  177.     base = com_base[1];     /* Default output to COM2 */
  178.  
  179.     strcpy(prog_name, argv[0]);  /* Get the name of the .EXE file */
  180.  
  181.     for (loop = 0; loop < strlen(prog_name); loop++) /* For each letter */
  182.     {
  183.         prog_name[loop] = tolower(prog_name[loop]);  /* Convert to lower case */
  184.     }
  185.  
  186.     ignore_local_maps = external_map = grey = blank = greymap =\
  187.         quiet = opterr = 0;
  188.  
  189.     while((c = getopt(argc,argv,OPTIONS)) != EOF)
  190.     {
  191.         switch(c)
  192.         {
  193.             case 'a':     if(!sscanf(optarg,"%x",&base))
  194.                               usage();
  195.                           break;
  196.  
  197.             case 'b':     blank = 1;
  198.                           break;
  199.  
  200.             case 'c':     base = com_base[atoi(optarg) - 1];
  201.                           break;
  202.  
  203.             case 'd':     debug = atoi(optarg);
  204.                           break;
  205.  
  206.             case 'g':     grey = 1;
  207.                           break;
  208.  
  209.             case 'i':     ignore_local_maps = 1;
  210.                           break;
  211.  
  212.             case 'm':     greymap = 1;
  213.                           break;
  214.  
  215.             case 'q':     quiet = 1;
  216.                           break;
  217.  
  218.             case 'p':     strcpy(map_file, optarg);
  219.                           external_map = 1;
  220.                           break;
  221.  
  222.             default:      usage();
  223.         }
  224.     }
  225.  
  226.     if ((gif_file = argv[optind]) == NULL)
  227.     {
  228.         printf("\nError: You _must_ supply an input file to view.\n");
  229.         usage();
  230.     }
  231.  
  232.     if ((f = fopen(gif_file, "rb")) == NULL)
  233.     {
  234.         fprintf(stderr, "File %s does not exist.\n", gif_file);
  235.         exit(-1);
  236.     }
  237.  
  238.     if (!debug)
  239.         Glasses(NONE);              /* Set both lenses clear */
  240.  
  241.     if (debug)
  242.       printf("\nFile: %s.\n\n", gif_file);
  243.  
  244.     fread(&Sig, 6, 1, f);       /* Read the header */
  245.  
  246.     if (strncmp(Sig, GIFSig, 3) != 0)
  247.     {
  248.         printf("File %s is not a valid '%.6s' GIF file.\n", argv[1], Sig);
  249.         close(f);
  250.         exit(-1);
  251.     }
  252.  
  253.     fread(&gd, sizeof(gd), 1, f);   /* Read the screen descriptor */
  254.  
  255.     global_map = gd.ColInfo >> 7;
  256.     bpp = (gd.ColInfo & 0x07) + 1;
  257.     colors = 1 << bpp;
  258.     lines = gd.Height;
  259.  
  260.     if ((debug == 3) || (debug == 4))
  261.         global_stats(&gd);
  262.  
  263.     if (!debug)
  264.     {
  265.         set320x400mode();               /* Jump into 320x400 mode */
  266.         if (grey)
  267.             disable_greyscale(0);
  268.         if (blank)
  269.             blank_screen(1);
  270.     }
  271.  
  272.     if (global_map)
  273.     {
  274.         fread(&pal, colors, 3, f);        /* Read global colormap */
  275.  
  276.         for(loop = 0; loop < colors; loop++)
  277.         {
  278.             pal[loop].r /= 4;
  279.             pal[loop].g /= 4;
  280.             pal[loop].b /= 4;
  281.         }
  282.  
  283.         if (!debug)
  284.             setvgapalette(&pal);            /* Set the palette from BIOS */
  285.     }
  286.  
  287.     /* All this is for the left image */
  288.  
  289.     separator = fgetc(f);           /* Read in the image separator ',' char */
  290.  
  291.     if (separator != 0x2c)
  292.     {
  293.         if (!debug)
  294.             end320x400mode();
  295.         printf("No image separator . Empty file: no image!\n");
  296.         printf("Character read is %c(%x)\n", separator, separator);
  297.         if (!debug)
  298.             exit(-1);
  299.     }
  300.  
  301.     fread(&id, sizeof(id), 1, f);   /* Read the image descriptor */
  302.  
  303.     local_map = id.Info >> 7;
  304.  
  305.     if (local_map)
  306.     {
  307.         if (!ignore_local_maps)      /* Abort if local map present */
  308.         {
  309.             if (!debug)
  310.                 end320x400mode();
  311.             printf("Found local color map in the first image..... Aborting.\n");
  312.             printf("If you wish to ignore the local maps and use the global\n");
  313.             printf("one, use the -i flag.\n");
  314.             if (!debug)
  315.                 exit(-1);
  316.         }
  317.  
  318.         bpp = (id.Info & 0x07) + 1;
  319.         colors = 1 << bpp;
  320.  
  321.         fread(&local_pal, colors, 1, f);     /* Read first local colormap */
  322.  
  323.         if (!global_map)
  324.         {
  325.             for (loop = 0; loop < colors; loop++)
  326.             {
  327.                 pal[loop].r = local_pal[loop].r / 4;
  328.                 pal[loop].g = local_pal[loop].g / 4;
  329.                 pal[loop].b = local_pal[loop].b / 4;
  330.             }
  331.             if (!debug)
  332.                 setvgapalette(&pal);       /* Set the palette from BIOS */
  333.         }
  334.         global_map = 1;
  335.     }
  336.  
  337.     if ((debug == 1) || (debug == 4))
  338.         local_stats(&id, separator);
  339.  
  340.     if (!debug)
  341.         setvispage(0);
  342.  
  343.     y = 0;
  344.     page = 0;
  345.  
  346.     if (!debug)
  347.         Glasses(LEFT);
  348.  
  349.     success1 = decoder(id.Width);
  350.  
  351.     error_count1 = bad_code_count;
  352.  
  353.     bad_code_count = 0;
  354.  
  355.     if (success1 != 0)
  356.     {
  357.         if (!debug)
  358.             end320x400mode();
  359.         printf("Error number %d in decoding of first image.\n", success1);
  360.         printf("Look in dgif.h.\n");
  361.         if (!debug)
  362.             exit(-1);
  363.  
  364.     }
  365.  
  366.     /* All this is for the right image */
  367.  
  368.     fgetc(f);                       /* Read in trailer code */
  369.  
  370.     separator = fgetc(f);           /* Read in the image separator ',' char */
  371.  
  372.     if (separator != 0x2c)
  373.     {
  374.         if (!debug)
  375.             end320x400mode();
  376.         printf("Single image GIF file: This is a stereo viewer!\n");
  377.         printf("Character read is %c(%x)\n", separator, separator);
  378.         if (!debug)
  379.             exit(-1);
  380.     }
  381.  
  382.     fread(&id, sizeof(id), 1, f);   /* Read in image descriptor */
  383.  
  384.  
  385.     local_map = id.Info >> 7;
  386.  
  387.     if (local_map)
  388.     {
  389.         if (!ignore_local_maps)      /* Abort if local map present */
  390.         {
  391.             if (!debug)
  392.                 end320x400mode();
  393.             printf("Found local color map in the second image..... Aborting.\n");
  394.             printf("If you wish to ignore the local maps and use the global\n");
  395.             printf("one, use the -i flag. The info byte is %c(0x%2x)\n", id.Info,\
  396.                                                                          id.Info);
  397.             if (!debug)
  398.                 exit(-1);
  399.         }
  400.  
  401.         bpp = (id.Info & 0x07) + 1;
  402.         colors = 1 << bpp;
  403.         fread(&local_pal, colors, 1, f);   /* Read second local colormap */
  404.  
  405.         if (!global_map)
  406.         {
  407.             for (loop = 0; loop < colors; loop++)
  408.             {
  409.                 pal[loop].r = local_pal[loop].r;
  410.                 pal[loop].g = local_pal[loop].g;
  411.                 pal[loop].b = local_pal[loop].b;
  412.             }
  413.             if (!debug)
  414.                 setvgapalette(&pal);       /* Set the palette from BIOS */
  415.         }
  416.         global_map = 1;
  417.     }
  418.  
  419.     if ((debug == 2) || (debug == 4))
  420.         local_stats(&id, separator);
  421.  
  422.     if (!debug)
  423.         setvispage(1);
  424.  
  425.     y = 0;
  426.     page = 1;
  427.  
  428.     if (!debug)
  429.         Glasses(RIGHT);
  430.  
  431.     success2 = decoder(id.Width);
  432.  
  433.     error_count2 = bad_code_count;
  434.  
  435.     close(f);
  436.  
  437.     if (success2 != 0)
  438.     {
  439.         if (!debug)
  440.             end320x400mode();
  441.         printf("Error number %d in decoding of second image.\n", success2);
  442.         printf("Look in dgif.h.\n");
  443.         if (!debug)
  444.             exit(-1);
  445.     }
  446.  
  447.     if (greymap)
  448.     {
  449.         for (loop = 0; loop < 255; loop++)
  450.         {
  451.             pal[loop].r = loop / 4;
  452.             pal[loop].g = loop / 4;
  453.             pal[loop].b = loop / 4;
  454.         }
  455.         if (!debug)
  456.             setvgapalette(&pal);       /* Set the palette from BIOS */
  457.     }
  458.  
  459.     if (external_map)
  460.     {
  461.         if ((f = fopen(map_file, "rb")) == NULL)
  462.         {
  463.             fprintf(stderr, "File %s does not exist.\n", gif_file);
  464.             exit(-1);
  465.         }
  466.  
  467.         for (loop = 0; loop < 255; loop++)
  468.             fscanf(f, "%d %d %d\n", &pal[loop].r, &pal[loop].g, &pal[loop].b);
  469.  
  470.         for (loop = 0; loop < 255; loop++)
  471.         {
  472.             pal[loop].r /= 4;
  473.             pal[loop].g /= 4;
  474.             pal[loop].b /= 4;
  475.         }
  476.  
  477.         setvgapalette(&pal);       /* Set the palette from BIOS */
  478.  
  479.         fclose(f);
  480.     }
  481.  
  482.     if (!debug)
  483.     {
  484.         if (blank)
  485.             blank_screen(0);
  486.         while (!kbhit())
  487.         {
  488.             WaitForVerticalRetrace();
  489.             Glasses(LEFT);
  490.             setvispage(0);
  491.             WaitForVerticalRetrace();
  492.             Glasses(RIGHT);
  493.             setvispage(1);
  494.         }
  495.  
  496.         getch();
  497.         Glasses(BOTH);
  498.         end320x400mode();
  499.         if (grey)
  500.             disable_greyscale(1);
  501.     }
  502.  
  503.     if (debug)
  504.     {
  505.         if (error_count1)
  506.             printf("Image one decoded with %d errors, returning code %d.\n\n",\
  507.                     error_count1, success1);
  508.         else
  509.             printf("No errors were found in image one.\n\n");
  510.  
  511.         if (error_count2)
  512.             printf("Image two decoded with %d errors, returning code %d.\n\n",\
  513.                     error_count2, success2);
  514.         else
  515.             printf("No errors were found in image two.\n\n");
  516.     }
  517.  
  518.     if (!quiet)
  519.     {
  520.         printf("The image '%s' has a resolution of %dx%d.\n", gif_file, id.Width, id.Height);
  521.         printf("Port address 0x%.4x was used for the glasses output.\n", base);
  522.         if (grey)
  523.             printf("GIF palette was changed to greyscale.\n");
  524.         if (greymap && global_map)
  525.             printf("GIF palette was ignored and greyscale used.\n");
  526.         else
  527.             if (greymap && !global_map)
  528.                 printf("GIF palette was not present, so greyscale used.\n");
  529.     }
  530. }
  531.